﻿using System;
using System.Linq;
using Terraria.ModLoader;
using MonoMod.Cil;
using Mono.Cecil.Cil;
using Terraria;
using Terraria.DataStructures;
using Terraria.ID;
using WorseGame.Common.Systems;
using WorseGame.Common.Players;
using WorseGame.Common.Configs;

namespace WorseGame.Common.Cores.Patches
{
    public class FishingPatches : ILoadable
    {
        public void Load(Mod mod)
        {
            IL_Player.ItemCheck_CheckFishingBobber_PullBobber += PullBobberCheck;
            On_Projectile.AI_061_FishingBobber += PreventBobberMovementWhileCatching;
            On_Projectile.FishingCheck_RollItemDrop += RerouteItemDetermination;
        }

        public void Unload() { }

        private void PullBobberCheck(ILContext il)
        {
            ILCursor c = new(il);
            if (c.TryGotoNext(i => i == c.Instrs.Last()))
            {
                c.Emit(OpCodes.Ldarg_1);
                c.EmitDelegate<Action<Projectile>>(bobber =>
                {
                    if (!SpecialConfig.Instance.FishingMinigame)
                        return;

                    if (bobber.ai[0] != 2f && (bobber.ai[1] < ItemID.OldShoe || bobber.ai[1] > ItemID.TinCan))
                    {
                        Main.player[bobber.owner].GetModPlayer<FishingPlayer>().StartCatchingFish(bobber);
                    }
                });
            }
        }

        private void PreventBobberMovementWhileCatching(On_Projectile.orig_AI_061_FishingBobber orig, Projectile self)
        {
            if (SpecialConfig.Instance.FishingMinigame)
            {
                if (Main.player[self.owner].GetModPlayer<FishingPlayer>().IsCatchingFish)
                {
                    self.ai[0] = 0;
                    self.ai[1] = -10f;
                }
            }

            orig(self);
        }

        private void RerouteItemDetermination(On_Projectile.orig_FishingCheck_RollItemDrop orig, Projectile self, ref FishingAttempt fisher)
        {
            if (!SpecialConfig.Instance.FishingMinigame)
            {
                orig(self, ref fisher);
                return;
            }

            if (fisher.rolledEnemySpawn > 0)
            {
                return;
            }
            fisher.rolledItemDrop = ModContent.GetInstance<CatchDeterminationSystem>().DetermineCatch(fisher, self);
            Main.player[self.owner].GetModPlayer<FishingPlayer>().currentFishingAttempt = fisher;
        }
    }
}